"use strict";

process.on("unhandledRejection", err => {
  throw err;
});

const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const execSync = require("child_process").execSync;
// const spawn = require('react-dev-utils/crossSpawn');
const os = require("os");
const scriptVersion = require("../package").version;
function isInGitRepository() {
  try {
    execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
    return true;
  } catch (e) {
    return false;
  }
}

function isInMercurialRepository() {
  try {
    execSync("hg --cwd . root", { stdio: "ignore" });
    return true;
  } catch (e) {
    return false;
  }
}

function tryGitInit(appPath) {
  let didInit = false;
  try {
    execSync("git --version", { stdio: "ignore" });
    if (isInGitRepository() || isInMercurialRepository()) {
      return false;
    }

    execSync("git init", { stdio: "ignore" });
    didInit = true;

    execSync("git add -A", { stdio: "ignore" });
    execSync('git commit -m "Initial commit from create-aife-app"', {
      stdio: "ignore"
    });
    return true;
  } catch (e) {
    if (didInit) {
      // If we successfully initialized but couldn't commit,
      // maybe the commit author config is not set.
      // In the future, we might supply our own committer
      // like Ember CLI does, but for now, let's just
      // remove the Git files to avoid a half-done state.
      try {
        // unlinkSync() doesn't work on directories.
        fs.removeSync(path.join(appPath, ".git"));
      } catch (removeErr) {
        // Ignore.
      }
    }
    return false;
  }
}

module.exports = function(appPath, appName, verbose, originalDirectory, template) {
  const ownPackageName = require(path.join(__dirname, "..", "package.json")).name;
  const ownPath = path.join(appPath, "node_modules", ownPackageName);
  const appPackage = require(path.join(appPath, "package.json"));
  const useYarn = fs.existsSync(path.join(appPath, "yarn.lock"));

  // Copy over some of the devDependencies
  appPackage.dependencies = appPackage.dependencies || {};

  // Setup the script rules
  appPackage.scripts = Object.assign({}, appPackage.scripts, {
    develop: "create-aife-app develop",
    prod: "create-aife-app prod"
  });
  //添加 example 代理
  appPackage.proxy = {
    "/*": {
      target: "localhost:3000",
      secure: false,
      changeOrigin: true,
      pathRewrite: {
        "^/example": ""
      }
    }
  };

  fs.writeFileSync(
    path.join(appPath, "package.json"),
    JSON.stringify(appPackage, null, 2) + os.EOL
  );

  const readmeExists = fs.existsSync(path.join(appPath, "README.md"));
  if (readmeExists) {
    fs.renameSync(path.join(appPath, "README.md"), path.join(appPath, "README.old.md"));
  }

  // Copy the files for the user
  let templatePath = "";
  if (template === "service") {
    templatePath = path.join(ownPath, "template/service");
  } else {
    templatePath = template
      ? path.resolve(originalDirectory, template)
      : path.join(ownPath, "template/basic");
  }

  if (fs.existsSync(templatePath)) {
    fs.copySync(templatePath, appPath);
  } else {
    console.error(`Could not locate supplied template: ${chalk.green(templatePath)}`);
    return;
  }

  // Rename gitignore after the fact to prevent npm from renaming it to .npmignore
  // See: https://github.com/npm/npm/issues/1862
  try {
    fs.moveSync(path.join(appPath, "gitignore"), path.join(appPath, ".gitignore"), []);
  } catch (err) {
    // Append if there's already a `.gitignore` file there
    if (err.code === "EEXIST") {
      const data = fs.readFileSync(path.join(appPath, "gitignore"));
      fs.appendFileSync(path.join(appPath, ".gitignore"), data);
      fs.unlinkSync(path.join(appPath, "gitignore"));
    } else {
      throw err;
    }
  }

  try {
    fs.moveSync(path.join(appPath, "npmrc"), path.join(appPath, ".npmrc"), []);
  } catch (err) {
    // Append if there's already a `.npmrc` file there
    if (err.code === "EEXIST") {
      const data = fs.readFileSync(path.join(appPath, "npmrc"));
      fs.appendFileSync(path.join(appPath, ".npmrc"), data);
      fs.unlinkSync(path.join(appPath, "npmrc"));
    } else {
      throw err;
    }
  }

  try {
    fs.moveSync(path.join(appPath, "yarnrc"), path.join(appPath, ".yarnrc"), []);
  } catch (err) {
    // Append if there's already a `.yarnrc` file there
    if (err.code === "EEXIST") {
      const data = fs.readFileSync(path.join(appPath, "yarnrc"));
      fs.appendFileSync(path.join(appPath, ".yarnrc"), data);
      fs.unlinkSync(path.join(appPath, "yarnrc"));
    } else {
      throw err;
    }
  }

  //  let command;
  //  let args;

  //  if (useYarn) {
  //    command = 'yarnpkg';
  //    args = ['add', "--dev"];
  //  } else {
  //    command = 'npm';
  //    args = ['install', '--save', verbose && '--verbose'].filter(e => e);
  //  }

  // Install additional template dependencies, if present
  //  const templateDependenciesPath = path.join(
  //    ownPath,
  //    '.template.dependencies.json'
  //  );
  //
  //  if (fs.existsSync(templateDependenciesPath)) {
  //    const templateDependencies = require(templateDependenciesPath).dependencies;
  //    args = args.concat(
  //      Object.keys(templateDependencies).map(key => {
  //        return `${key}@${templateDependencies[key]}`;
  //      })
  //    );
  //    fs.unlinkSync(templateDependenciesPath);
  //
  //    console.log(`Installing template dev dependencies using ${command}...`);
  //    console.log();
  //
  //    const proc = spawn.sync(command, args, { stdio: 'inherit' });
  //    if (proc.status !== 0) {
  //      console.error(`\`${command} ${args.join(' ')}\` failed`);
  //      return;
  //    }
  //  }

  if (tryGitInit(appPath)) {
    console.log();
    console.log("Initialized a git repository.");
  }

  // Display the most elegant way to cd.
  // This needs to handle an undefined originalDirectory for
  // backward compatibility with old global-cli's.
  let cdpath;
  if (originalDirectory && path.join(originalDirectory, appName) === appPath) {
    cdpath = appName;
  } else {
    cdpath = appPath;
  }

  // Change displayed command to yarn instead of yarnpkg
  const displayedCommand = useYarn ? "yarn" : "npm";

  console.log();
  console.log(`Success! Created ${appName} at ${appPath}`);
  console.log("Inside that directory, you can run several commands:");
  console.log();
  console.log(chalk.cyan(`  ${displayedCommand} run develop`));
  console.log("    Starts the development server.");
  console.log();
  console.log(chalk.cyan(`run prod`));
  console.log("    Bundles the app into static files for production.");
  console.log();
  console.log("We suggest that you begin by typing:");
  console.log();
  console.log(chalk.cyan("  cd"), cdpath);
  console.log(`  ${chalk.cyan(`${displayedCommand} run develop`)}`);
  if (readmeExists) {
    console.log();
    console.log(chalk.yellow("You had a `README.md` file, we renamed it to `README.old.md`"));
  }
  console.log();
};

// function isReactInstalled(appPackage) {
//   const dependencies = appPackage.dependencies || {};

//   return (
//     typeof dependencies.react !== 'undefined' &&
//     typeof dependencies['react-dom'] !== 'undefined'
//   );
// }
